package com.mdms.jsf.managedbeans.user;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;


import com.mdms.commands.user.ClientContext;
import com.mdms.commands.user.GetUserRights;
import com.mdms.commands.user.UserCommand;
import com.mdms.dto.UdtUsers;
import com.mdms.jsf.managedbeans.BaseMBean;
import com.mdms.jsf.managedbeans.menu.NavigationMenuMBean;
import com.mdms.logger.SimplyMDLogger;
import com.mdms.utils.FacesUtils;
import com.mdms.utils.MDmsLoginContext;

public class UserMBean extends BaseMBean {

	private final static SimplyMDLogger logger = new SimplyMDLogger(UserMBean.class);

	protected boolean correctLogin = false;

	private ClientContext clientContext;

	/** czy trzeba zmienic haslo */
	protected boolean changePassword = false;

	/** usre zalogowany */
	private boolean isAlreadyLogin = false;
	
	private String userName;
	
	private String userEmail;


	private String userLayoutId = null;

	private String locale = "";

	private String login;

	private String password ;

	private String md5Password;

	private List<String> errorMeassage;


	public String loginUser(){
		String methodName = "loginUser";
		logger.debug(methodName, "START");
		errorMeassage = new ArrayList<String>();
		if(authenticateUser(getLogin(), getPassword())){
			if(changePassword){
				return "change_password";
			}
			userLayoutId=FacesUtils.getLayout();
			MDmsLoginContext.setContext(getPropsForLoginContext(clientContext));
			SecurityMBean securityMBean = new SecurityMBean();
			GetUserRights getUserRightsCommand = new GetUserRights();
			try{
			getUserRightsCommand.setClientContext(clientContext);
			getUserRightsCommand.setUser_id(new Long(clientContext.getUsr_id()));
			getUserRightsCommand.execute();
			if(getUserRightsCommand.errorCode==0){
				securityMBean.setRightsMap(getUserRightsCommand.getRightsMap());
				securityMBean.setClientContext(clientContext);
				FacesUtils.setManagedBeanValue("securityMBean", securityMBean);
			}
			}catch (Exception e){
				logger.error(methodName, e);
			}
			logger.debug(methodName, "END");
			return "succes";
		}
		logger.debug(methodName, "END");
		return "loginPage";
	}
		
	public String logoutUser(){
		String methodName = "logoutuser";
		logger.debug(methodName, "START");
		setAlreadyLogin(false);
		invalidateSession();
		logger.debug(methodName, "END");
		return "logout";
	}


	protected boolean authenticateUser(String usrName,String usrPassword){

		String methodName = "authenticateUser";
		logger.debug(methodName, "START");
		correctLogin = false;
		changePassword = false;
		ClientContext context = new ClientContext();
		UserCommand command = new UserCommand(clientContext);
		command.setLogin(usrName);
		try{
			command.execute();
			if(command.getErrorCode()==0){
				UdtUsers users = command.getUsers();
				if(users==null){
					errorMeassage.add("MESSAGE ERROR FROM BUNDLE");
					return correctLogin;
				}
				if(users.getUsr_password().equals(getMd5Password())){
					correctLogin=true;
				}else{
					errorMeassage.add("RESOURCES PASSWORD ERROR");
				}
				setAlreadyLogin(true);
				ClientContext clientContext = new ClientContext();
				clientContext.setUsr_name(users.getUsr_login());
				clientContext.setUsr_id(users.getUsr_id().toString());
				clientContext.setSsn_ip(getUserIP());
				clientContext.setSsn_id("0");
				userName=users.getUsr_name()+" "+users.getUsr_sname();
				userEmail=users.getUsr_email();
				setClientContext(clientContext);
				FacesUtils.setManagedBeanValue("userMBean", this);
			}else{
				logger.error(methodName,command.getErrorCode(),command.getErrorDesc());
				errorMeassage.add(command.getErrorDesc());
			}

		}catch(Exception e){
			logger.error(methodName,e);
		}
		logger.debug(methodName, "END");
		return correctLogin;
	}

	public void invalidateSession() {
		Object session = FacesContext.getCurrentInstance().getExternalContext().getSession(false);
		if (session != null && session instanceof HttpSession) {
			((HttpSession) session).invalidate();
		}
	}

	public String getUserIP() {
		String userIP = "";
		FacesContext facesContext = FacesContext.getCurrentInstance();
		Object request = facesContext.getExternalContext().getRequest();
		if (request instanceof HttpServletRequest) {
			//userIP = ((HttpServletRequest) request).getRemoteAddr();
			if (((HttpServletRequest) request).getHeader("X-Forwarded-For") == null){
				userIP = ((HttpServletRequest) request).getRemoteAddr();
			} else {
				userIP = ((HttpServletRequest) request).getHeader("X-Forwarded-For");
				if(userIP != null) {
					// jezeli jest kilka IP biezemy tylko pierwszy - powinien to byc IP clienta
					int commaIndex = userIP.indexOf(',');
					if(commaIndex > 0) {
						userIP = userIP.substring(0, commaIndex);
					}
				}
			}
			if (userIP == null || userIP.length() == 0) {
				//JsfUtils.reportError("login.error.noIP", new RuntimeException("Lack of client IP adress in header "),
				//logger);
			}
		}

		logger.debug("getUserIP", "Loging attempt from IP: " + userIP);

		return userIP;
	}

	private Properties getPropsForLoginContext(ClientContext clientContext){
		Properties props = new Properties();
		props.put(MDmsLoginContext.USER_ID, clientContext.getUsr_id());
		props.put(MDmsLoginContext.SSN_IP, clientContext.getSsn_ip());
		props.put(MDmsLoginContext.SSN_ID, clientContext.getSsn_id());

		return props;
	}

	public String getLogin() {
		return login;
	}

	public void setLogin(String login) {
		this.login = login;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}


	public boolean isCorrectLogin() {
		return correctLogin;
	}


	public void setCorrectLogin(boolean correctLogin) {
		this.correctLogin = correctLogin;
	}


	public boolean isAlreadyLogin() {
		return isAlreadyLogin;
	}


	public void setAlreadyLogin(boolean isAlreadyLogin) {
		this.isAlreadyLogin = isAlreadyLogin;
	}


	public String getLocale() {
		return locale;
	}


	public void setLocale(String locale) {
		this.locale = locale;
	}


	public List<String> getErrorMeassage() {
		return errorMeassage;
	}


	public void setErrorMeassage(List<String> errorMeassage) {
		this.errorMeassage = errorMeassage;
	}


	public ClientContext getClientContext() {
		return clientContext;
	}


	public void setClientContext(ClientContext clientContext) {
		this.clientContext = clientContext;
	}


	public String getMd5Password() {
		return md5Password;
	}


	public void setMd5Password(String md5Password) {
		this.md5Password = md5Password;
	}

	public String getUserLayoutId() {
		if (userLayoutId==null ||
				"".equals(userLayoutId)){
			userLayoutId = FacesUtils.getLayout();
		}
		if (userLayoutId==null ||
				"".equals(userLayoutId)){
			userLayoutId = "0";
		}
		return userLayoutId;
	}

	public void setUserLayoutId(String userLayoutId) {
		this.userLayoutId = userLayoutId;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getUserEmail() {
		return userEmail;
	}

	public void setUserEmail(String userEmail) {
		this.userEmail = userEmail;
	}
	
	


}
